package org.fast.easy.system.upms.controller;

import cn.dev33.satoken.secure.BCrypt;
import cn.hutool.core.bean.BeanUtil;
import com.google.gson.JsonObject;
import jakarta.validation.constraints.NotNull;
import lombok.RequiredArgsConstructor;

import org.fast.easy.core.domain.auth.model.LoginUser;
import org.fast.easy.core.domain.page.PageQuery;
import org.fast.easy.core.domain.page.TableDataInfo;
import org.fast.easy.core.domain.result.R;
import org.fast.easy.core.util.StringUtils;
import org.fast.easy.framework.encrypt.annotation.ApiEncrypt;
import org.fast.easy.framework.log.enums.BusinessType;
import org.fast.easy.framework.satoken.utils.LoginHelper;
import org.fast.easy.framework.web.core.BaseController;
import org.fast.easy.system.monitor.domain.bo.SysLogininforBo;
import org.fast.easy.system.monitor.domain.bo.SysOperLogBo;
import org.fast.easy.system.monitor.domain.vo.SysLogininforVo;
import org.fast.easy.system.monitor.domain.vo.SysOperLogVo;
import org.fast.easy.system.monitor.service.ISysLogininforService;
import org.fast.easy.system.monitor.service.ISysOperLogService;
import org.fast.easy.system.upms.domain.bo.SysUserBo;
import org.fast.easy.system.upms.domain.bo.SysUserPasswordBo;
import org.fast.easy.system.upms.domain.bo.SysUserProfileBo;
import org.fast.easy.system.upms.domain.entity.SysMenu;
import org.fast.easy.system.upms.domain.vo.*;
import org.fast.easy.system.upms.service.ISysMenuService;
import org.fast.easy.system.upms.service.ISysUserService;
import org.fast.easy.system.upms.service.ISysUserShortcutMenuService;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.fast.easy.framework.log.annotation.Log;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.Month;
import java.time.YearMonth;
import java.time.format.DateTimeFormatter;
import java.util.*;

/**
 * 个人信息 业务处理
 *
 * @author Lion Li
 */
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/system/user/profile")
public class SysProfileController extends BaseController {

    private final ISysUserService userService;

    private final ISysUserShortcutMenuService userShortcutMenuService;
    private final ISysMenuService menuService;
    private final ISysLogininforService logininforService;

    private final ISysOperLogService operLogService;

    /**
     * 个人信息
     */
    @GetMapping
    public R<ProfileVo> profile() {
        SysUserVo user = userService.selectUserById(LoginHelper.getUserId());
        ProfileVo profileVo = new ProfileVo();
        profileVo.setUser(user);
        profileVo.setRoleGroup(userService.selectUserRoleGroup(user.getUserName()));
        profileVo.setPostGroup(userService.selectUserPostGroup(user.getUserName()));
        return R.ok(profileVo);
    }

    /**
     * 修改用户
     */
    @Log(title = "个人信息", businessType = BusinessType.UPDATE)
    @PutMapping
    public R<Void> updateProfile(@RequestBody SysUserProfileBo profile) {
        SysUserBo user = BeanUtil.toBean(profile, SysUserBo.class);
        String username = LoginHelper.getUsername();
        if (StringUtils.isNotEmpty(user.getPhonenumber()) && !userService.checkPhoneUnique(user)) {
            return R.fail("修改用户'" + username + "'失败，手机号码已存在");
        }
        if (StringUtils.isNotEmpty(user.getEmail()) && !userService.checkEmailUnique(user)) {
            return R.fail("修改用户'" + username + "'失败，邮箱账号已存在");
        }
        user.setUserId(LoginHelper.getUserId());
        if (userService.updateUserProfile(user) > 0) {
            return R.ok();
        }
        return R.fail("修改个人信息异常，请联系管理员");
    }

    /**
     * 重置密码
     *
     * @param bo 新旧密码
     */
    @ApiEncrypt
    @Log(title = "个人信息", businessType = BusinessType.UPDATE)
    @PutMapping("/updatePwd")
    public R<Void> updatePwd(@Validated @RequestBody SysUserPasswordBo bo) {
        SysUserVo user = userService.selectUserById(LoginHelper.getUserId());
        String password = user.getPassword();
        if (!BCrypt.checkpw(bo.getOldPassword(), password)) {
            return R.fail("修改密码失败，旧密码错误");
        }
        if (BCrypt.checkpw(bo.getNewPassword(), password)) {
            return R.fail("新密码不能与旧密码相同");
        }

        if (userService.resetUserPwd(user.getUserId(), BCrypt.hashpw(bo.getNewPassword())) > 0) {
            return R.ok();
        }
        return R.fail("修改密码异常，请联系管理员");
    }




    /**
     * 获取用户快捷菜单信息
     *
     * @return 用户快捷菜单信息
     */
    @GetMapping("/getUserShortcutMenuInfo")
    public R<List<SysUserShortcutMenuVo>> getUserShortcutMenuInfo() {
        List<SysUserShortcutMenuVo> userShortcutMenuVoList = null;
        LoginUser loginUser = LoginHelper.getLoginUser();
        if(loginUser!=null){
            userShortcutMenuVoList = userShortcutMenuService.selectShortcutMenuList();
            if(userShortcutMenuVoList==null || userShortcutMenuVoList.size()==0 ){
                List<SysMenuVo> menuList = menuService.selectMenuList(loginUser.getUserId());
                userShortcutMenuVoList = userShortcutMenuService.initShortcutMenuList(menuList);
            }
        }
        return R.ok(userShortcutMenuVoList);
    }


    @GetMapping("/setUserShortcutMenuInfo/{menuId}")
    public R<Void> setUserShortcutMenuInfo(@PathVariable @NotNull Long menuId) {
        LoginUser loginUser = LoginHelper.getLoginUser();
        if(loginUser!=null){
            userShortcutMenuService.updateShortcutMenuUsed(menuId);
        }
        return R.ok();
    }


    @PostMapping("/setUserShortcutMenuPath")
    public R<Void> setUserShortcutMenuPath(@RequestBody HashMap<String, String> map) {
        LoginUser loginUser = LoginHelper.getLoginUser();
        if(loginUser!=null){
            if(map!=null){
                Long menuId = null;
                String path = map.get("path");
                if(StringUtils.isNotBlank(path)){
                    List<SysMenu> list = menuService.selectMenuFullPathAllList();
                    if(list!=null){
                        for(SysMenu menu : list){
                            if(path.equals(menu.getPath())){
                                if(menu.getMenuId()!=null){
                                    userShortcutMenuService.updateShortcutMenuUsed(menu.getMenuId());
                                    break;
                                }
                            }

                        }

                    }
                }

            }
        }
        return R.ok();
    }

    @GetMapping(value = {"/getUserMonthScheduleCount"})
    public R<UserMonthScheduleCount> getUserMonthScheduleCount(@RequestParam(value = "year", required = false) Integer year, @RequestParam(value = "month", required = false) Integer month) {
        UserMonthScheduleCount userMonthScheduleCount = null;
        LoginUser loginUser = LoginHelper.getLoginUser();
        if(loginUser!=null) {
            Month currentMonthEnum = null;
            if (year == null || year <= 0) {
                // 直接获取当前年份的数值，LocalDate.now()用于获取当前日期，然后通过.getYear()获取年份的数值。
                year = LocalDate.now().getYear();
            }
            if (month == null || month <= 0 || month > 12) {
                // 直接获取当前月份的枚举值，LocalDate.now()用于获取当前日期，然后通过.getMonthValue()获取月份的数值（1-12），或通过.getMonth()获取Month枚举类型，表示具体的月份名称。
                currentMonthEnum = LocalDate.now().getMonth();
                month = currentMonthEnum.getValue();
            }
            // 创建YearMonth对象
            YearMonth yearMonth = YearMonth.of(year, month);
            // 获取该月的最大天数
            int maxDays = yearMonth.lengthOfMonth();

            userMonthScheduleCount = new UserMonthScheduleCount(year, month);

            for(int d =0; d<maxDays; d++){
                int count = 0;
                if(d%3 == 0){
                    count = d;
                }
                userMonthScheduleCount.getDayCount()[d] = count;
            }
        }
        return R.ok(userMonthScheduleCount);
    }
    @PostMapping("/getUserDayScheduleList")
    public R<List<SysUserScheduleDateVo>> getUserDayScheduleList(@RequestBody HashMap<String, String> map) {
        List<SysUserScheduleDateVo> scheduleList = null;
        LoginUser loginUser = LoginHelper.getLoginUser();
        if(loginUser!=null){
            if(map!=null){
                String date = map.get("date");
                if(StringUtils.isNotBlank(date)){
                    scheduleList = new ArrayList<>();

                    List<SysUserScheduleVo> list  = new ArrayList<>();
                    for(int j =1;j<5;j++){
                        SysUserScheduleVo schedule = new SysUserScheduleVo();
                        String[] scheduleDateTime = {date+" 09:00",date+" 12:00"};
                        schedule.setScheduleDateTime(scheduleDateTime);
                    }
                    SysUserScheduleDateVo scheduleDateVo = new SysUserScheduleDateVo();
                    scheduleDateVo.setDate(date);
                    scheduleDateVo.setList(list);
                    scheduleList.add(scheduleDateVo);
                }
            }
        }
        return R.ok(scheduleList);
    }

    @GetMapping("/loginLog")
    public TableDataInfo<SysLogininforVo> loginLogList( ) {
        TableDataInfo<SysLogininforVo> tableDataInfo = new TableDataInfo<>();
        LoginUser loginUser = LoginHelper.getLoginUser();
        if(loginUser!=null) {
            PageQuery pageQuery = new PageQuery();
            pageQuery.setPageNum(1);
            pageQuery.setPageSize(10);
            pageQuery.setIsAsc("desc");
            pageQuery.setOrderByColumn("login_time");

            SysLogininforBo logininfor = new SysLogininforBo();
            logininfor.setTenantId(loginUser.getTenantId());
            logininfor.setUserName(loginUser.getUsername());
            logininfor.setUserId(loginUser.getUserId());
            return logininforService.selectPageLogininforList(logininfor, pageQuery);
        }
        return tableDataInfo;
    }

    @GetMapping("/operateLog")
    public TableDataInfo<SysOperLogVo> operateLogList( ) {
        TableDataInfo<SysOperLogVo> tableDataInfo = new TableDataInfo<>();
        LoginUser loginUser = LoginHelper.getLoginUser();
        if(loginUser!=null) {
            PageQuery pageQuery = new PageQuery();
            pageQuery.setPageNum(1);
            pageQuery.setPageSize(10);
            pageQuery.setIsAsc("desc");
            pageQuery.setOrderByColumn("login_time");

            SysOperLogBo operLog = new SysOperLogBo();
            operLog.setTenantId(loginUser.getTenantId());
            operLog.setUserId(loginUser.getUserId());
            return operLogService.selectPageOperLogList(operLog, pageQuery);
        }
        return tableDataInfo;
    }
}
